package com.jcode.netty.core;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;

import java.util.concurrent.ExecutorService;

import com.jcode.netty.exception.RemotingSendRequestException;
import com.jcode.netty.exception.RemotingTimeoutException;
import com.jcode.netty.exception.RemotingTooMuchRequestException;
import com.jcode.netty.protocol.Packet;

/**
 * 远程服务接口
 * 启动、停止、读写数据，处理请求
 *
 * @Author dreajay
 * @DateTime 2016年12月6日 下午2:28:30
 *
 */
public interface RemotingService {

	/**
	 * 启动
	 */
	void start();

	/**
	 * 停止
	 */
	void shutdown();

	/**
	 * 获取默认请求处理线程池
	 * 
	 * @return
	 */
	ExecutorService getDefaultRequestExecutor();

	/**
	 * 获取异步回调处理线程池
	 * 
	 * @return
	 */
	ExecutorService getCallbackExecutor();

	/**
	 * 注册处理器
	 * 
	 * @param requestCode
	 *            请求码
	 * @param processor
	 *            处理器
	 * @param executor
	 *            线程池
	 *            如果null会使用默认ExecutorService
	 */
	void registerProcessor(final int requestCode, final RequestProcessor processor, final ExecutorService executor);

	/**
	 * 处理消息接入
	 * 
	 * @param ctx
	 * @param packet
	 */
	public void processMessageReceived(final ChannelHandlerContext ctx, final Packet packet);

	/**
	 * 处理请求
	 * 
	 * @param ctx
	 * @param packet
	 */
	public void processRequest(final ChannelHandlerContext ctx, final Packet packet);

	/**
	 * 处理响应
	 * 
	 * @param ctx
	 * @param packet
	 */
	public void processResponse(final ChannelHandlerContext ctx, final Packet packet);

	/**
	 * 发送同步请求
	 * 
	 * @param channel
	 * @param packet
	 * @param timeoutMillis
	 * @return
	 * @throws InterruptedException
	 * @throws RemotingSendRequestException
	 * @throws RemotingTimeoutException
	 */
	public Packet sendRequestSync(final Channel channel, final Packet packet, final long timeoutMillis) throws InterruptedException, RemotingSendRequestException, RemotingTimeoutException;

	/**
	 * 发送异步请求
	 * 
	 * @param channel
	 * @param packet
	 * @param timeoutMillis
	 * @param callback
	 * @throws InterruptedException
	 * @throws RemotingSendRequestException
	 * @throws RemotingTimeoutException
	 * @throws RemotingTooMuchRequestException
	 */
	public void sendRequestAsync(final Channel channel, final Packet packet, final long timeoutMillis, final ResponseCallback callback) throws InterruptedException, RemotingSendRequestException, RemotingTimeoutException, RemotingTooMuchRequestException;

	/**
	 * 发送单向请求，接收方无响应内容
	 * 
	 * @param channel
	 * @param packet
	 * @param timeoutMillis
	 * @throws InterruptedException
	 * @throws RemotingSendRequestException
	 * @throws RemotingTimeoutException
	 * @throws RemotingTooMuchRequestException
	 */
	public void sendRequestOneway(final Channel channel, final Packet packet, final long timeoutMillis) throws InterruptedException, RemotingSendRequestException, RemotingTimeoutException, RemotingTooMuchRequestException;
}
